package io.gitee.zhangbinhub.admin.component

import io.gitee.zhangbinhub.acp.core.common.CalendarTools
import io.gitee.zhangbinhub.acp.core.common.security.SM3Encrypt
import org.springframework.stereotype.Component

/**
 * 密码加解密工具类
 */
@Component
class AuthPasswordEncrypt {
    /**
     * 密码加密（用于存储）
     * @param loginNo 登录账号
     * @param password 密码明文
     * @return 加密后的存储密文
     */
    fun encrypt(loginNo: String, password: String) = SM3Encrypt.encrypt(SM3Encrypt.encrypt(password) + loginNo)

    /**
     * 密码加密（用于登录）
     * @param encryptedPassword 加密后的密码存储密文
     * @return 加密后的验证密文
     */
    fun encryptForLogin(encryptedPassword: String) =
        encryptForLogin(encryptedPassword, CalendarTools.getDateTimeString(dateTimeFormat = "yyyyMMddHH"))

    /**
     * 密码登录验证
     * @param rawPassword 用户输入的密码
     * @param encryptedPassword 加密后的密码存储密文
     * @return true|false
     */
    fun matches(rawPassword: String, encryptedPassword: String): Boolean =
        CalendarTools.getNowDateTime().let { now ->
            for (o in -OFFSET..OFFSET) {
                val password = encryptForLogin(
                    encryptedPassword,
                    CalendarTools.getDateTimeString(now.plusHours(o), "yyyyMMddHH")
                )
                if (rawPassword.equals(password, ignoreCase = true)) {
                    return true
                }
            }
            return false
        }

    /**
     * 密码加密（用于登录）
     * @param encryptedPassword 加密后的密码存储密文
     * @param factor 加密因子
     * @return 加密后的验证密文
     */
    private fun encryptForLogin(encryptedPassword: String, factor: String) =
        SM3Encrypt.encrypt(encryptedPassword + factor)

    companion object {
        private const val OFFSET = 1
    }
}